package org.bigjava.novelplatform.service.impl;

import cn.hutool.core.io.FileUtil;
import lombok.SneakyThrows;
import org.bigjava.novelplatform.common.utils.RedisUtils;
import org.bigjava.novelplatform.entity.Recommend;
import org.bigjava.novelplatform.mapper.BooksMapper;
import org.bigjava.novelplatform.service.RecommendService;
import org.bigjava.novelplatform.vo.BookVoList;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.File;
import java.time.Duration;
import java.util.*;

import static org.bigjava.novelplatform.common.constant.NovelInfoConstant.*;
import static org.bigjava.novelplatform.common.utils.RedisBuildKey.BOOK_REDIS_KEY_LIST;

@Service
public class RecommendServiceImpl implements RecommendService {
    @Resource
    BooksMapper booksMapper;
    @Resource
    RedisUtils redisUtils;

    /**
     * 添加一个推荐
     */
    @SneakyThrows
    @Override
    public boolean addRecommend(Recommend rec, MultipartFile multipartFile) {
        if (null == rec.getType() & null == rec.getName() & null == rec.getBody() & null == rec.getRegion()) {
            return false;
        }
        String key = String.valueOf(System.currentTimeMillis());//单个推荐的key
        rec.setId(key);
//        System.out.println("文件内容类型:" + multipartFile.getContentType());
        /**
         * FileUtil.writeFromStream() 将流的内容写入文件 此方法会自动关闭输入流
         * multipartFile.getInputStream() 获取输入流对象ByteArrayInputStream
         * 不必关闭ByteArrayInputStream,当它没有被任何变量引用时,垃圾收集器将释放流并且somebytes(当然假设它们未在其他地方引用)
         * FileUtil.touch() 创建文件及其父目录，如果这个文件存在，直接返回这个文件 此方法不对File对象类型做判断，如果File不存在，无法判断其类型
         * */
//        File file = FileUtil.writeFromStream(multipartFile.getInputStream(), FileUtil.touch("C:\\Users\\XMZR\\Desktop\\resource\\img\\" + rec.getId() + ".jpg"));
        if (multipartFile != null) {
            multipartFile.transferTo(new File(EXTENSION_DISK_PATH + rec.getId() + ".jpg"));
            rec.setImgUrl(EXTENSION_PREFIX + rec.getId() + ".jpg");
        }


        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);

        //从未操作过redis
        if (null == map) {
            Map<String, List<String>> map1 = new HashMap<>();
            ArrayList<String> list = new ArrayList<>();
            map1.put(rec.getType(), list);
            redisUtils.set(map1, "Recommend", null);
            map = map1;
        }

        List<String> list = new ArrayList<>();
        if (!map.containsKey(rec.getType())) {//没有该类型的推荐 创建该类型

            map.put(rec.getType(), list);
//            redisUtils.set(map, "Recommend", null);
//            map = redisUtils.parseJsonToMap("Recommend", String.class);
        }else{
            list = map.get(rec.getType());
        }

        //存放单个推荐
        redisUtils.set(rec, key, null);


        list.add(key);
//        map.put(rec.getType(), list);
        redisUtils.set(map, "Recommend", null);//更新redis中的数据
        return true;
    }

    /**
     * 删除一个推荐
     */
    @Override
    public boolean deleteRecommend(String key) {
        redisUtils.set(null, key, Duration.ofNanos(10));
        return false;
    }

    /**
     * 获取指定key的推荐内容
     */
    @Override
    public HashMap<String, String> getBodyByKey(String key) {
        return redisUtils.parseJsonToObject(key, HashMap.class);
    }

    /**
     * 获取所有推荐的key集合
     */
    @Override
    public List<String> getRecommendList() {
        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);
        if (null == map) {
            return null;
        }
        Set<String> stringSet = map.keySet();
        List<String> list = new ArrayList<String>();
        for (String s : stringSet) {
            for (String s1 : map.get(s)) {
                list.add(s1);
            }
        }
        return list;
    }

    /**
     * 获取指定类型的推荐的key集合
     */
    @Override
    public List<String> getKeyListByType(String type) {
        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);
        if (null == map) {
            return null;
        }
        if (map.containsKey(type)) {
            return null;
        }
        return map.get(type);
    }

    /**
     * 添加一个推荐类型
     */
    @Override
    public boolean addType(String type) {
        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);
        //如果redis中不存在该key对应的数据
        if (null == map) {
            return false;
        }

        //如果map、中存在该(rec.getType) key 返回true
        if (map.containsKey(type)) {
            return false;
        }

        ArrayList<String> list = new ArrayList<>();
        map.put(type, list);
        redisUtils.set(map, "Recommend", null);
        return true;
    }

    @Override
    public void removeKey(String key) {
        Recommend recommend = redisUtils.parseJsonToObject(key, Recommend.class);

        //删除map存储的key
        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);
        List<String> strings = map.get(recommend.getType());
        for (int i = 0; i <strings.size(); i++) {
            if(strings.get(i).equals(recommend.getId())){
                strings.remove(i);
                break;
            }
        }
        redisUtils.set(map, "Recommend", null);

        //在redis中删除
        redisUtils.del(recommend.getId());

    }

    @Override
    public List<BookVoList> getSuggestVoByInput(String input) {
        return booksMapper.selectAllByBookVoList(input);
    }


    @Override
    public List<Recommend> getAllRecommendByType(String type) {
        Map<String, List<String>> recommend = redisUtils.parseJsonToMap("Recommend", String.class);
        if (recommend == null) {
            return null;
        }
        List<String> strings = recommend.get(type);
        ArrayList<Recommend> recommends = new ArrayList<>();
        if (strings != null) {
            for (String string : strings) {
                recommends.add(redisUtils.parseJsonToObject(string, Recommend.class));
            }
        }
        return recommends;
    }

    @Override
    public List<String> getAllType() {
        Map<String, List<String>> map = redisUtils.parseJsonToMap("Recommend", String.class);
        List<String> list = new ArrayList<String>();
        if (null == map) {
            return list;
        }
        Set<String> stringSet = map.keySet();

        for (String s : stringSet) {
            list.add(s);
        }
        return list;
    }
}
